From 226d32217a013608410e222a7270c9816ca0b170 Mon Sep 17 00:00:00 2001 From: Timo Tijhof Date: Sat, 14 Apr 2012 09:35:18 +0200 Subject: [PATCH] (bug 35769) Convert mediawiki.Uri test suite to QUnit - Converted ./tests/jasmine/spec/mediawiki.Uri.spec.js to ./tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js - expect('').toContain('') doesn't exist in QUnit, changed to ok(''.indexOf('') >= 0), which is what Jasmine does internally. - Some of the Jasmine expects()'s didn't have descriptions, added those while at it. - Cleaned up the 1 test that was already in QUnit added in 2d84f3191a9ebf18bcc1b833fd6b7d3666f91f8e. - Cleaned up SpecRunner.html Change-Id: Id7b498888e22576e8ff0636725191624add470d6 --- tests/jasmine/SpecRunner.html | 58 +-- tests/jasmine/spec/mediawiki.Uri.spec.js | 320 -------------- .../resources/mediawiki/mediawiki.Uri.test.js | 405 +++++++++++++++++- 3 files changed, 415 insertions(+), 368 deletions(-) delete mode 100644 tests/jasmine/spec/mediawiki.Uri.spec.js diff --git a/tests/jasmine/SpecRunner.html b/tests/jasmine/SpecRunner.html index 6af9b0c393..63d0fdfa7e 100644 --- a/tests/jasmine/SpecRunner.html +++ b/tests/jasmine/SpecRunner.html @@ -1,42 +1,28 @@ - - - - Jasmine Test Runner - - - + + + + Jasmine Test Runner + + + + - - - - + + + - - - - + + - - - - - - - - - + + + - - + diff --git a/tests/jasmine/spec/mediawiki.Uri.spec.js b/tests/jasmine/spec/mediawiki.Uri.spec.js deleted file mode 100644 index e396ab3188..0000000000 --- a/tests/jasmine/spec/mediawiki.Uri.spec.js +++ /dev/null @@ -1,320 +0,0 @@ -( function() { - - // ensure we have a generic URI parser if not running in a browser - if ( !mw.Uri ) { - mw.Uri = mw.UriRelative( 'http://example.com/' ); - } - - describe( "mw.Uri", function() { - - describe( "should work well in loose and strict mode", function() { - - function basicTests( strict ) { - - describe( "should parse a simple HTTP URI correctly", function() { - - var uriString = 'http://www.ietf.org/rfc/rfc2396.txt'; - var uri; - if ( strict ) { - uri = new mw.Uri( uriString, strict ); - } else { - uri = new mw.Uri( uriString ); - } - - it( "should have basic object properties", function() { - expect( uri.protocol ).toEqual( 'http' ); - expect( uri.host ).toEqual( 'www.ietf.org' ); - expect( uri.port ).not.toBeDefined(); - expect( uri.path ).toEqual( '/rfc/rfc2396.txt' ); - expect( uri.query ).toEqual( {} ); - expect( uri.fragment ).not.toBeDefined(); - } ); - - describe( "should construct composite components of URI on request", function() { - it( "should have empty userinfo", function() { - expect( uri.getUserInfo() ).toEqual( '' ); - } ); - - it( "should have authority equal to host", function() { - expect( uri.getAuthority() ).toEqual( 'www.ietf.org' ); - } ); - - it( "should have hostport equal to host", function() { - expect( uri.getHostPort() ).toEqual( 'www.ietf.org' ); - } ); - - it( "should have empty string as query string", function() { - expect( uri.getQueryString() ).toEqual( '' ); - } ); - - it( "should have path as relative path", function() { - expect( uri.getRelativePath() ).toEqual( '/rfc/rfc2396.txt' ); - } ); - - it( "should return a uri string equivalent to original", function() { - expect( uri.toString() ).toEqual( uriString ); - } ); - } ); - } ); - } - - describe( "should work in loose mode", function() { - basicTests( false ); - } ); - - describe( "should work in strict mode", function() { - basicTests( true ); - } ); - - } ); - - it( "should parse a simple ftp URI correctly with user and password", function() { - var uri = new mw.Uri( 'ftp://usr:pwd@192.0.2.16/' ); - expect( uri.protocol ).toEqual( 'ftp' ); - expect( uri.user ).toEqual( 'usr' ); - expect( uri.password ).toEqual( 'pwd' ); - expect( uri.host ).toEqual( '192.0.2.16' ); - expect( uri.port ).not.toBeDefined(); - expect( uri.path ).toEqual( '/' ); - expect( uri.query ).toEqual( {} ); - expect( uri.fragment ).not.toBeDefined(); - } ); - - it( "should parse a simple querystring", function() { - var uri = new mw.Uri( 'http://www.google.com/?q=uri' ); - expect( uri.protocol ).toEqual( 'http' ); - expect( uri.host ).toEqual( 'www.google.com' ); - expect( uri.port ).not.toBeDefined(); - expect( uri.path ).toEqual( '/' ); - expect( uri.query ).toBeDefined(); - expect( uri.query ).toEqual( { q: 'uri' } ); - expect( uri.fragment ).not.toBeDefined(); - expect( uri.getQueryString() ).toEqual( 'q=uri' ); - } ); - - describe( "should handle multiple value query args (overrideKeys on)", function() { - var uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', { overrideKeys: true } ); - it ( "should parse with multiple values", function() { - expect( uri.query.m ).toEqual( 'bar' ); - expect( uri.query.n ).toEqual( '1' ); - } ); - it ( "should accept multiple values", function() { - uri.query.n = [ "x", "y", "z" ]; - expect( uri.toString() ).toContain( 'm=bar' ); - expect( uri.toString() ).toContain( 'n=x&n=y&n=z' ); - expect( uri.toString().length ).toEqual( 'http://www.example.com/dir/?m=bar&n=x&n=y&n=z'.length ); - } ); - } ); - - describe( "should handle multiple value query args (overrideKeys off)", function() { - var uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', { overrideKeys: false } ); - it ( "should parse with multiple values", function() { - expect( uri.query.m.length ).toEqual( 2 ); - expect( uri.query.m[0] ).toEqual( 'foo' ); - expect( uri.query.m[1] ).toEqual( 'bar' ); - expect( uri.query.n ).toEqual( '1' ); - } ); - it ( "should accept multiple values", function() { - uri.query.n = [ "x", "y", "z" ]; - expect( uri.toString() ).toContain( 'm=foo&m=bar' ); - expect( uri.toString() ).toContain( 'n=x&n=y&n=z' ); - expect( uri.toString().length ).toEqual( 'http://www.example.com/dir/?m=foo&m=bar&n=x&n=y&n=z'.length ); - } ); - it ( "should be okay with removing values", function() { - uri.query.m.splice( 0, 1 ); - delete uri.query.n; - expect( uri.toString() ).toEqual( 'http://www.example.com/dir/?m=bar' ); - uri.query.m.splice( 0, 1 ); - expect( uri.toString() ).toEqual( 'http://www.example.com/dir/' ); - } ); - } ); - - describe( "should deal with an all-dressed URI with everything", function() { - var uri = new mw.Uri( 'http://auth@www.example.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value+%28escaped%29#top' ); - - it( "should have basic object properties", function() { - expect( uri.protocol ).toEqual( 'http' ); - expect( uri.user ).toEqual( 'auth' ); - expect( uri.password ).not.toBeDefined(); - expect( uri.host ).toEqual( 'www.example.com' ); - expect( uri.port ).toEqual( '81' ); - expect( uri.path ).toEqual( '/dir/dir.2/index.htm' ); - expect( uri.query ).toEqual( { q1: '0', test1: null, test2: 'value (escaped)' } ); - expect( uri.fragment ).toEqual( 'top' ); - } ); - - describe( "should construct composite components of URI on request", function() { - it( "should have userinfo", function() { - expect( uri.getUserInfo() ).toEqual( 'auth' ); - } ); - - it( "should have authority equal to auth@hostport", function() { - expect( uri.getAuthority() ).toEqual( 'auth@www.example.com:81' ); - } ); - - it( "should have hostport equal to host:port", function() { - expect( uri.getHostPort() ).toEqual( 'www.example.com:81' ); - } ); - - it( "should have query string which contains all components", function() { - var queryString = uri.getQueryString(); - expect( queryString ).toContain( 'q1=0' ); - expect( queryString ).toContain( 'test1' ); - expect( queryString ).not.toContain( 'test1=' ); - expect( queryString ).toContain( 'test2=value+%28escaped%29' ); - } ); - - it( "should have path as relative path", function() { - expect( uri.getRelativePath() ).toContain( uri.path ); - expect( uri.getRelativePath() ).toContain( uri.getQueryString() ); - expect( uri.getRelativePath() ).toContain( uri.fragment ); - } ); - - } ); - } ); - - describe( "should be able to clone itself", function() { - var original = new mw.Uri( 'http://en.wiki.local/w/api.php?action=query&foo=bar' ); - var clone = original.clone(); - - it( "should make clones equivalent", function() { - expect( original ).toEqual( clone ); - expect( original.toString() ).toEqual( clone.toString() ); - } ); - - it( "should be able to manipulate clones independently", function() { - // but they are still different objects - expect( original ).not.toBe( clone ); - // and can diverge - clone.host = 'fr.wiki.local'; - expect( original.host ).not.toEqual( clone.host ); - expect( original.toString() ).not.toEqual( clone.toString() ); - } ); - } ); - - describe( "should be able to construct URL from object", function() { - it ( "should construct given basic arguments", function() { - var uri = new mw.Uri( { protocol: 'http', host: 'www.foo.local', path: '/this' } ); - expect( uri.toString() ).toEqual( 'http://www.foo.local/this' ); - } ); - - it ( "should construct given more complex arguments", function() { - var uri = new mw.Uri( { - protocol: 'http', - host: 'www.foo.local', - path: '/this', - query: { hi: 'there' }, - fragment: 'blah' - } ); - expect( uri.toString() ).toEqual( 'http://www.foo.local/this?hi=there#blah' ); - } ); - - it ( "should fail to construct without required properties", function() { - expect( function() { - var uri = new mw.Uri( { protocol: 'http', host: 'www.foo.local' } ); - } ).toThrow( "Bad constructor arguments" ); - } ); - } ); - - describe( "should be able to manipulate properties", function() { - var uri; - - beforeEach( function() { - uri = new mw.Uri( 'http://en.wiki.local/w/api.php' ); - } ); - - it( "can add a fragment", function() { - uri.fragment = 'frag'; - expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php#frag' ); - } ); - - it( "can change host and port", function() { - uri.host = 'fr.wiki.local'; - uri.port = '8080'; - expect( uri.toString() ).toEqual( 'http://fr.wiki.local:8080/w/api.php' ); - } ); - - it ( "can add query arguments", function() { - uri.query.foo = 'bar'; - expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php?foo=bar' ); - } ); - - it ( "can extend query arguments", function() { - uri.query.foo = 'bar'; - expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php?foo=bar' ); - uri.extend( { foo: 'quux', pif: 'paf' } ); - expect( uri.toString() ).toContain( 'foo=quux' ); - expect( uri.toString() ).not.toContain( 'foo=bar' ); - expect( uri.toString() ).toContain( 'pif=paf' ); - } ); - - it ( "can remove query arguments", function() { - uri.query.foo = 'bar'; - expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php?foo=bar' ); - delete( uri.query.foo ); - expect( uri.toString() ).toEqual( 'http://en.wiki.local/w/api.php' ); - } ); - - } ); - - describe( "should handle protocol-relative URLs", function() { - var uriRel = mw.UriRelative( 'glork://en.wiki.local/foo.php' ); - - it ( "should create protocol-relative URLs with same protocol as document", function() { - var uri = new uriRel( '//en.wiki.local/w/api.php' ); - expect( uri.protocol ).toEqual( 'glork' ); - } ); - - it( "should handle absolute paths by supplying protocol and host from document in loose mode", function() { - var uri = new uriRel( '/foo.com' ); - expect( uri.toString() ).toEqual( 'glork://en.wiki.local/foo.com' ); - } ); - - it( "should handle absolute paths by supplying host from document in loose mode", function() { - var uri = new uriRel( 'http:/foo.com' ); - expect( uri.toString() ).toEqual( 'http://en.wiki.local/foo.com' ); - } ); - - it( "should handle absolute paths by supplying protocol and host from document in strict mode", function() { - var uri = new uriRel( '/foo.com', true ); - expect( uri.toString() ).toEqual( 'glork://en.wiki.local/foo.com' ); - } ); - - it( "should handle absolute paths by supplying host from document in strict mode", function() { - var uri = new uriRel( 'http:/foo.com', true ); - expect( uri.toString() ).toEqual( 'http://en.wiki.local/foo.com' ); - } ); - } ); - - it( "should throw error on no arguments to constructor", function() { - expect( function() { - var uri = new mw.Uri(); - } ).toThrow( "Bad constructor arguments" ); - } ); - - it( "should throw error on empty string as argument to constructor", function() { - expect( function() { - var uri = new mw.Uri( '' ); - } ).toThrow( "Bad constructor arguments" ); - } ); - - it( "should throw error on non-URI as argument to constructor", function() { - expect( function() { - var uri = new mw.Uri( 'glaswegian penguins' ); - } ).toThrow( "Bad constructor arguments" ); - } ); - - it( "should throw error on URI without protocol or // or leading / in strict mode", function() { - expect( function() { - var uri = new mw.Uri( 'foo.com/bar/baz', true ); - } ).toThrow( "Bad constructor arguments" ); - } ); - - it( "should normalize URI without protocol or // in loose mode", function() { - var uri = new mw.Uri( 'foo.com/bar/baz', false ); - expect( uri.toString() ).toEqual( 'http://foo.com/bar/baz' ); - } ); - - } ); - -} )(); diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js index fcdcd21d96..552e69e303 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.Uri.test.js @@ -1,26 +1,407 @@ module( 'mediawiki.Uri', QUnit.newMwEnvironment() ); -test( '-- Initial check', function() { +test( '-- Initial check', function () { + expect( 2 ); + + // Ensure we have a generic URI parser if not running in a browser + if ( !mw.Uri ) { + mw.Uri = mw.UriRelative( 'http://example.com/' ); + } + + ok( mw.UriRelative, 'mw.UriRelative defined' ); + ok( mw.Uri, 'mw.Uri defined' ); +} ); + +$.each( [true, false], function ( i, strictMode ) { + test( 'Basic mw.Uri object test in ' + ( strictMode ? '' : 'non-' ) + 'strict mode for a simple HTTP URI', function () { + var uriString, uri; + expect( 2 ); + + uriString = 'http://www.ietf.org/rfc/rfc2396.txt'; + uri = new mw.Uri( uriString, { + strictMode: strictMode + }); + + deepEqual( + { + protocol: uri.protocol, + host: uri.host, + port: uri.port, + path: uri.path, + query: uri.query, + fragment: uri.fragment + }, { + protocol: 'http', + host: 'www.ietf.org', + port: undefined, + path: '/rfc/rfc2396.txt', + query: {}, + fragment: undefined + }, + 'basic object properties' + ); + + deepEqual( + { + userInfo: uri.getUserInfo(), + authority: uri.getAuthority(), + hostPort: uri.getHostPort(), + queryString: uri.getQueryString(), + relativePath: uri.getRelativePath(), + toString: uri.toString() + }, + { + userInfo: '', + authority: 'www.ietf.org', + hostPort: 'www.ietf.org', + queryString: '', + relativePath: '/rfc/rfc2396.txt', + toString: uriString + }, + 'construct composite components of URI on request' + ); + + }); +}); + +test( 'Parse an ftp URI correctly with user and password', function () { + var uri; expect( 1 ); - ok( mw.UriRelative, 'mw.Uri defined' ); + uri = new mw.Uri( 'ftp://usr:pwd@192.0.2.16/' ); + + deepEqual( + { + protocol: uri.protocol, + user: uri.user, + password: uri.password, + host: uri.host, + port: uri.port, + path: uri.path, + query: uri.query, + fragment: uri.fragment + }, + { + protocol: 'ftp', + user: 'usr', + password: 'pwd', + host: '192.0.2.16', + port: undefined, + path: '/', + query: {}, + fragment: undefined + }, + 'basic object properties' + ); +} ); + +test( 'Parse a uri with simple querystring', function () { + var uri; + expect( 1 ); + + uri = new mw.Uri( 'http://www.google.com/?q=uri' ); + + deepEqual( + { + protocol: uri.protocol, + host: uri.host, + port: uri.port, + path: uri.path, + query: uri.query, + fragment: uri.fragment, + queryString: uri.getQueryString() + }, + { + protocol: 'http', + host: 'www.google.com', + port: undefined, + path: '/', + query: { q: 'uri' }, + fragment: undefined, + queryString: 'q=uri' + }, + 'basic object properties' + ); +} ); + +test( 'Handle multiple query parameter (overrideKeys on)', function () { + var uri; + expect( 5 ); + + uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', { + overrideKeys: true + }); + + equal( uri.query.n, '1', 'multiple parameters are parsed' ); + equal( uri.query.m, 'bar', 'last key overrides earlier keys' ); + + uri.query.n = [ 'x', 'y', 'z' ]; + + // Verify parts and total length instead of entire string because order + // of iteration can vary. + ok( uri.toString().indexOf( 'm=bar' ), 'toString preserves other values' ); + ok( uri.toString().indexOf( 'n=x&n=y&n=z' ), 'toString parameter includes all values of an array query parameter' ); + equal( uri.toString().length, 'http://www.example.com/dir/?m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' ); } ); -test( 'mw.Uri bug 35658', function() { +test( 'Handle multiple query parameter (overrideKeys off)', function () { + var uri; + expect( 9 ); + + uri = new mw.Uri( 'http://www.example.com/dir/?m=foo&m=bar&n=1', { + overrideKeys: false + }); + + // Strict comparison so that types are also verified (n should be string '1') + strictEqual( uri.query.m.length, 2, 'multi-value query should be an array with 2 items' ); + strictEqual( uri.query.m[0], 'foo', 'order and value is correct' ); + strictEqual( uri.query.m[1], 'bar', 'order and value is correct' ); + strictEqual( uri.query.n, '1', 'n=1 is parsed with the correct value of the expected type' ); + + // Change query values + uri.query.n = [ 'x', 'y', 'z' ]; + + // Verify parts and total length instead of entire string because order + // of iteration can vary. + ok( uri.toString().indexOf( 'm=foo&m=bar' ) >= 0, 'toString preserves other values' ); + ok( uri.toString().indexOf( 'n=x&n=y&n=z' ) >= 0, 'toString parameter includes all values of an array query parameter' ); + equal( uri.toString().length, 'http://www.example.com/dir/?m=foo&m=bar&n=x&n=y&n=z'.length, 'toString matches expected string' ); + + // Remove query values + uri.query.m.splice( 0, 1 ); + delete uri.query.n; + + equal( uri.toString(), 'http://www.example.com/dir/?m=bar', 'deletion properties' ); + + // Remove more query values, leaving an empty array + uri.query.m.splice( 0, 1 ); + equal( uri.toString(), 'http://www.example.com/dir/', 'empty array value is ommitted' ); +} ); + +test( 'All-dressed URI with everything', function () { + var uri, queryString, relativePath; + expect( 11 ); + + uri = new mw.Uri( 'http://auth@www.example.com:81/dir/dir.2/index.htm?q1=0&&test1&test2=value+%28escaped%29#top' ); + + deepEqual( + { + protocol: uri.protocol, + user: uri.user, + password: uri.password, + host: uri.host, + port: uri.port, + path: uri.path, + query: uri.query, + fragment: uri.fragment + }, + { + protocol: 'http', + user: 'auth', + password: undefined, + host: 'www.example.com', + port: '81', + path: '/dir/dir.2/index.htm', + query: { q1: '0', test1: null, test2: 'value (escaped)' }, + fragment: 'top' + }, + 'basic object properties' + ); + + equal( uri.getUserInfo(), 'auth', 'user info' ); + + equal( uri.getAuthority(), 'auth@www.example.com:81', 'authority equal to auth@hostport' ); + + equal( uri.getHostPort(), 'www.example.com:81', 'hostport equal to host:port' ); + + queryString = uri.getQueryString(); + ok( queryString.indexOf( 'q1=0' ) >= 0, 'query param with numbers' ); + ok( queryString.indexOf( 'test1' ) >= 0, 'query param with null value is included' ); + ok( queryString.indexOf( 'test1=' ) === -1, 'query param with null value does not generate equals sign' ); + ok( queryString.indexOf( 'test2=value+%28escaped%29' ) >= 0, 'query param is url escaped' ); + + relativePath = uri.getRelativePath(); + ok( relativePath.indexOf( uri.path ) >= 0, 'path in relative path' ); + ok( relativePath.indexOf( uri.getQueryString() ) >= 0, 'query string in relative path' ); + ok( relativePath.indexOf( uri.fragment ) >= 0, 'fragement in relative path' ); +} ); + +test( 'Cloning', function () { + var original, clone; + expect( 5 ); + + original = new mw.Uri( 'http://en.wiki.local/w/api.php?action=query&foo=bar' ); + clone = original.clone(); + + deepEqual( clone, original, 'clone has equivalent properties' ); + equal( original.toString(), clone.toString(), 'toString matches original' ); + + notStrictEqual( clone, original, 'clone is not the same when compared by reference' ); + + clone.host = 'fr.wiki.local'; + notEqual( original.host, clone.host, 'manipulating clone did not effect original' ); + notEqual( original.toString(), clone.toString(), 'toString no longer matches original' ); +} ); + +test( 'Constructing mw.Uri from plain object', function () { + var uri; + expect( 3 ); + + uri = new mw.Uri({ + protocol: 'http', + host: 'www.foo.local', + path: '/this' + }); + equal( uri.toString(), 'http://www.foo.local/this', 'Basic properties' ); + + uri = new mw.Uri({ + protocol: 'http', + host: 'www.foo.local', + path: '/this', + query: { hi: 'there' }, + fragment: 'blah' + }); + equal( uri.toString(), 'http://www.foo.local/this?hi=there#blah', 'More complex properties' ); + + raises( + function () { + var uri = new mw.Uri({ + protocol: 'http', + host: 'www.foo.local' + }); + }, + function ( e ) { + return e.message === 'Bad constructor arguments'; + }, + 'Construction failed when missing required properties' + ); +} ); + +test( 'Manipulate properties', function () { + var uriBase, uri; + expect( 8 ); + + uriBase = new mw.Uri( 'http://en.wiki.local/w/api.php' ); + + uri = uriBase.clone(); + uri.fragment = 'frag'; + equal( uri.toString(), 'http://en.wiki.local/w/api.php#frag', 'add a fragment' ); + + uri = uriBase.clone(); + uri.host = 'fr.wiki.local'; + uri.port = '8080'; + equal( uri.toString(), 'http://fr.wiki.local:8080/w/api.php', 'change host and port' ); + + uri = uriBase.clone(); + uri.query.foo = 'bar'; + equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'add query arguments' ); + + delete uri.query.foo; + equal( uri.toString(), 'http://en.wiki.local/w/api.php', 'delete query arguments' ); + + uri = uriBase.clone(); + uri.query.foo = 'bar'; + equal( uri.toString(), 'http://en.wiki.local/w/api.php?foo=bar', 'extend query arguments' ); + uri.extend({ + foo: 'quux', + pif: 'paf' + }); + ok( uri.toString().indexOf( 'foo=quux' ) >= 0, 'extend query arguments' ); + ok( uri.toString().indexOf( 'foo=bar' ) === -1, 'extend query arguments' ); + ok( uri.toString().indexOf( 'pif=paf' ) >= 0 , 'extend query arguments' ); +} ); + +test( 'Handle protocol-relative URLs', function () { + var UriRel, uri; + expect( 5 ); + + UriRel = mw.UriRelative( 'glork://en.wiki.local/foo.php' ); + + uri = new UriRel( '//en.wiki.local/w/api.php' ); + equal( uri.protocol, 'glork', 'create protocol-relative URLs with same protocol as document' ); + + uri = new UriRel( '/foo.com' ); + equal( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in loose mode' ); + + uri = new UriRel( 'http:/foo.com' ); + equal( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in loose mode' ); + + uri = new UriRel( '/foo.com', true ); + equal( uri.toString(), 'glork://en.wiki.local/foo.com', 'handle absolute paths by supplying protocol and host from document in strict mode' ); + + uri = new UriRel( 'http:/foo.com', true ); + equal( uri.toString(), 'http://en.wiki.local/foo.com', 'handle absolute paths by supplying host from document in strict mode' ); +} ); + +test( 'Bad calls', function () { + var uri; + expect( 5 ); + + raises( + function () { + new mw.Uri(); + }, + function ( e ) { + return e.message === 'Bad constructor arguments'; + }, + 'throw error on no arguments to constructor' + ); + + raises( + function () { + new mw.Uri( '' ); + }, + function ( e ) { + return e.message === 'Bad constructor arguments'; + }, + 'throw error on empty string as argument to constructor' + ); + + raises( + function () { + new mw.Uri( 'glaswegian penguins' ); + }, + function ( e ) { + return e.message === 'Bad constructor arguments'; + }, + 'throw error on non-URI as argument to constructor' + ); + + raises( + function () { + new mw.Uri( 'foo.com/bar/baz', { + strictMode: true + }); + }, + function ( e ) { + return e.message === 'Bad constructor arguments'; + }, + 'throw error on URI without protocol or // or leading / in strict mode' + ); + + uri = new mw.Uri( 'foo.com/bar/baz', { + strictMode: false + }); + equal( uri.toString(), 'http://foo.com/bar/baz', 'normalize URI without protocol or // in loose mode' ); +}); + +test( 'bug 35658', function () { expect( 2 ); - var testProtocol = 'https://'; - var testServer = 'foo.example.org'; - var testPort = '3004'; - var testPath = '/!1qy'; + var testProtocol, testServer, testPort, testPath, UriClass, uri, href; - var uriClass = mw.UriRelative( testProtocol + testServer + '/some/path/index.html' ); - var uri = new uriClass( testPath ); - var href = uri.toString(); + testProtocol = 'https://'; + testServer = 'foo.example.org'; + testPort = '3004'; + testPath = '/!1qy'; + + UriClass = mw.UriRelative( testProtocol + testServer + '/some/path/index.html' ); + uri = new UriClass( testPath ); + href = uri.toString(); equal( href, testProtocol + testServer + testPath, 'Root-relative URL gets host & protocol supplied' ); - uriClass = mw.UriRelative( testProtocol + testServer + ':' + testPort + '/some/path.php' ); - uri = new uriClass( testPath ); + UriClass = mw.UriRelative( testProtocol + testServer + ':' + testPort + '/some/path.php' ); + uri = new UriClass( testPath ); href = uri.toString(); equal( href, testProtocol + testServer + ':' + testPort + testPath, 'Root-relative URL gets host, protocol, and port supplied' ); -- 2.20.1